-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Allow duck ai chat syncing (Internal) #7377
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: feature/craig/update_sync_crypto_apis_byte_array
Are you sure you want to change the base?
Allow duck ai chat syncing (Internal) #7377
Conversation
|
Warning This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
This stack of pull requests is managed by Graphite. Learn more about stacking. |
2f70f7b to
9cc09c0
Compare
d36ea31 to
32ff896
Compare
9cc09c0 to
827e026
Compare
0c92c2f to
76cd1e5
Compare
861bb89 to
344aba4
Compare
e268906 to
3d1db92
Compare
a0131a0 to
671c8c0
Compare
b8f6d64 to
c46ac61
Compare
3fea8ee to
2f2edb4
Compare
c46ac61 to
b706df5
Compare
2f2edb4 to
6300bf8
Compare
b2e25e9 to
8fad7c6
Compare
6300bf8 to
7c494c7
Compare
8fad7c6 to
68609b8
Compare
7c494c7 to
f32b677
Compare
68609b8 to
fa156a9
Compare
f32b677 to
dcde3d7
Compare
4f4a176 to
5eacdaa
Compare
afa24c5 to
4dd2d33
Compare
05596f0 to
610d556
Compare
ef3085d to
cbfdecb
Compare
c95cc23 to
dce0017
Compare
610d556 to
7e9d370
Compare
de0f738 to
80efa15
Compare
7e9d370 to
fea3179
Compare
80efa15 to
59d202c
Compare
duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/helper/DuckChatJSHelper.kt
Show resolved
Hide resolved
...ckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/messaging/sync/Base64UrlExtensions.kt
Show resolved
Hide resolved
...src/main/java/com/duckduckgo/duckchat/impl/messaging/sync/DecryptWithSyncMasterKeyHandler.kt
Show resolved
Hide resolved
...src/main/java/com/duckduckgo/duckchat/impl/messaging/sync/DecryptWithSyncMasterKeyHandler.kt
Show resolved
Hide resolved
|
|
||
| fun sendError(error: String) { | ||
| val errorPayload = JSONObject().apply { | ||
| put("ok", false) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we use the same payload in several classes, can we extract the keys (or perhaps even better, a class we can serialize/deserialize)?
duckchat/duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/store/DuckChatDataStore.kt
Show resolved
Hide resolved
...kchat-impl/src/main/java/com/duckduckgo/duckchat/impl/sync/DuckAiChatDeletionListenerImpl.kt
Outdated
Show resolved
Hide resolved
| override fun onStop(owner: LifecycleOwner) { | ||
| appBackgroundedTimestamp = System.currentTimeMillis() | ||
| logcat { "DuckChat-Sync: App went to background, stored timestamp: $appBackgroundedTimestamp" } | ||
| val timestamp = System.currentTimeMillis() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we use CurrentTimeProvider instead?
| return null | ||
| } | ||
|
|
||
| return runBlocking(dispatchers.io()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know runBlocking was already here before, but do we need it? Can we rely on observables instead now that RC flags support it?
| import javax.inject.Inject | ||
|
|
||
| @ContributesMultibinding(AppScope::class) | ||
| class DecryptWithSyncMasterKeyHandler @Inject constructor( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a lot of duplicated code in these handlers. Can we refactor them to avoid that?
59d202c to
5cb7a5c
Compare
fea3179 to
5ec43f6
Compare
...kchat-impl/src/main/java/com/duckduckgo/duckchat/impl/sync/DuckAiChatDeletionListenerImpl.kt
Show resolved
Hide resolved
.../duckchat-impl/src/main/java/com/duckduckgo/duckchat/impl/messaging/sync/SetUpSyncHandler.kt
Show resolved
Hide resolved
|
|
||
| jsMessaging.onResponse(JsCallbackData(jsonPayload, featureName, jsMessage.method, jsMessage.id!!)).also { | ||
| logcat { "DuckChat-Sync: responded to ${jsMessage.method} with $jsonPayload" } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing exception handling for JS response could cause crash
Medium Severity
The jsMessaging.onResponse() call at line 75 is not wrapped in runCatching, unlike all other handlers in this PR (DecryptWithSyncMasterKeyHandler, EncryptWithSyncMasterKeyHandler, SetUpSyncHandler, GetScopedSyncAuthTokenHandler) which consistently protect this call with exception handling. If onResponse() throws an exception, it would propagate uncaught and potentially crash the app, whereas the other handlers gracefully log the error and continue.

Task/Issue URL: https://app.asana.com/1/137249556945/project/488551667048375/task/1212450128487247?focus=true
Description
Enables duck AI chat syncing for internal builds.
For testing, will require 2 or more devices/emulators, and each will need to be configured to hit duck chat internal config, details below.
Setting up for testing (do on each of the test devices)
internalbuild type from this branchai.duckduckgo.cominto the omnibar, and authorise yourself by signing inPRODUCTION - setup and go to duck.aiAgree and Continuewhen duck ai chat launchesINTERNALbadgeSteps to test this PR
Logcat filter:
message~:"DuckChat-Sync|getAIChatNativeConfigValues"Syncing some chats between devices
Pre-requisite - set up sync between the two test devices
Settings -> Sync & Backup -> Sync and Back Up This Deviceto completionSync With Another Deviceand chooseCopy Text CodeSettings -> Sync & Backupand chooseSync With Another Device. TapManually Enter CodeandPaste Code.This should set up Device A and Device B to sync with each other.
Test steps
Native fire button
Settings -> Data Clearingand enableClear Duck.ai ChatsValidate feature flag gates feature
aiChatSyncfeature flag on Device A. Kill app and re-open."supportsAIChatSync":falseaiChatSync. Kill app and re-open.#### Testing when sync is disabled
Settings -> Sync & Backup -> Turn Off Sync & Backup...overflow (top-left) -> SettingsSet Up Now. Tap it, verify you are taken to sync setup. Hit back button and verify you still see theSet Up Nowbutton.Sync and Back Up This Device).Set Up Nowbutton disappears (might not be immediate)Note
Enables internal Duck AI chat syncing end-to-end across app, JS, and Sync layers.
supportsAIChatSynctogetAIChatNativeConfigValuesencryptWithSyncMasterKey/decryptWithSyncMasterKey(base64url utils)setAIChatHistoryEnabled(persisted flag)sendToSyncSettings/sendToSetupSyncgetScopedSyncAuthToken(rescope) andgetSyncStatusDuckAiChatDeletionListenerImplstores background timestamp;DuckChatSyncDataManagernow gates deletions on chat history enabledtoken/rescope, switch dev URL to staging, delete AI chats endpoint covered; new handlers/testsWritten by Cursor Bugbot for commit 89e6b67. This will update automatically on new commits. Configure here.